#include "ModelFileLoader.h"

#include <chrono>
#include <QDebug>

class ScopeTimer {
public:
    ScopeTimer(const QString& name) : m_name(name) {
        m_start = std::chrono::high_resolution_clock::now();
    }

    ~ScopeTimer() {
        stop();
    }

    void stop() {
        if (m_stopped) return;

        auto end = std::chrono::high_resolution_clock::now();
        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - m_start);
        qDebug() << "[" << m_name << "] 耗时:"
                 << duration.count() / 1000.0 << "ms ("
                 << duration.count() << "μs)";
        m_stopped = true;
    }

private:
    QString m_name;
    std::chrono::time_point<std::chrono::high_resolution_clock> m_start;
    bool m_stopped = false;
};

// 使用宏简化
// 修复后的宏定义
#define CONCAT_(a, b) a##b
#define CONCAT(a, b) CONCAT_(a, b)
#define SCOPED_TIMER(name) ScopeTimer CONCAT(timer_, __LINE__)(name)

QImage cvMatToQImage(const cv::Mat &frame)
{
    // 由于入参是引用，注意会被槽函数触发抢掉锁，从而导致frame引用的变量
    QImage image;
    switch(frame.type())
    {
    case CV_8UC1:
        // QImage构造：数据，宽度，高度，每行多少字节，存储结构
        image = QImage((const unsigned char*)frame.data, frame.cols, frame.rows, frame.step, QImage::Format_Grayscale8);
        break;
    case CV_8UC3:
        image = QImage((const unsigned char*)frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGBA8888).rgbSwapped();
        break;
    case CV_8UC4:
        image = QImage((const unsigned char*)frame.data, frame.cols, frame.rows, frame.step, QImage::Format_ARGB32);
        break;
    case CV_16UC4:
        image = QImage((const unsigned char*)frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGBA64).rgbSwapped();// BRG转为RGB
        break;
    }
    return image;
}

void FilterDemo(const std::string& imagePath, QImage &w) {
    // 读取图像
    cv::Mat original = cv::imread(imagePath);

    if (original.empty()) {
        qDebug() << "无法读取图像: " << imagePath;
        return;
    }

    qDebug() << original.cols << " " << original.rows << " " <<original.channels() << " " << original.type();

    // 应用均值漂移滤波
    cv::Mat filtered;
    // cv::pyrMeanShiftFiltering(original, filtered, 15, 30, 2);
    // 双边滤波 - 速度比均值漂移快很多
    cv::bilateralFilter(original, filtered, 9, 75, 75);
    w = cvMatToQImage(filtered);
}

bool ModelFileLoader::load(const QString &filePath)
{
    // QDir appDir(QCoreApplication::applicationDirPath());
    // // QString fullPath_diff = "Image_0.jpg";
    // QString fullPath_diff = appDir.filePath("tripo_image_d0cf1034-6ea9-4400-97b4-44862b0b79ef_0.jpg");
    // // QString fullPath_diff = appDir.filePath("tripo_image_a2ce597c-ef15-4bd2-ac66-a7d5352a5495_0.jpg");
    // // QString fullPath_diff = appDir.filePath("cpu_tex_diff_0.png");
    // QString fullPath_spec = appDir.filePath("cpu_tex_spec_0.png");

    // if (!QFile::exists(fullPath_diff) || !QFile::exists(fullPath_spec)) {
    //     qWarning() << "纹理文件不存在：" << fullPath_diff << " 或 " << fullPath_spec;
    // }

    // if (!m_textureDiffImage.load(fullPath_diff)) {
    //     qWarning() << "无法加载纹理：" << fullPath_diff;
    // }
    // else
    //     m_textureDiffImage = m_textureDiffImage.convertToFormat(QImage::Format_RGBA8888);

    // if (!m_textureSpecImage.load(fullPath_spec)) {
    //     qWarning() << "无法加载纹理：" << fullPath_spec;
    // }
    // else
    //     m_textureSpecImage = m_textureSpecImage.convertToFormat(QImage::Format_RGBA8888);

    // FilterDemo(fullPath_diff.toStdString(), m_textureDiffImage);

    // 重置状态
    m_loaded = false;
    m_lastError.clear();
    m_vertices.clear();
    m_indices.clear();
    m_edges.clear();
    m_triangles.clear();
    m_materials.clear();
    m_lights.clear();

    // 保存模型文件所在目录
    QFileInfo fileInfo(filePath);
    m_modelDirectory = fileInfo.absolutePath();

    // 使用Assimp加载模型
    const aiScene* scene = m_importer.ReadFile(
        filePath.toUtf8().constData(),
        aiProcess_Triangulate |        // 三角化所有多边形
            // aiProcess_GenSmoothNormals |   // 生成平滑法线
            aiProcess_FlipUVs |            // 翻转UV（OpenGL纹理原点在左下角）
            // aiProcess_CalcTangentSpace |   // 计算切线空间（使用法线贴图时开启，用于法线映射）
            aiProcess_JoinIdenticalVertices // 合并相同顶点
        );

    if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
    {
        m_lastError = QString("Assimp加载失败: %1").arg(m_importer.GetErrorString());
        return false;
    }

    m_scene = scene;


    // 处理材质
    m_materials.reserve(m_scene->mNumMaterials);
    for (unsigned int i = 0; i < m_scene->mNumMaterials; ++i)
    {
        Material mat;
        processMaterial(m_scene->mMaterials[i], mat);
        m_materials.push_back(mat);
    }

    // 填充 CPU 用的纹理图像
    fillImageWithTexture(m_materials);

    // 处理几何图元
    processNode(m_scene->mRootNode, m_scene);

    // 处理灯光
    processLights(m_scene);

    m_loaded = true;
    return true;
}

bool ModelFileLoader::isLoaded() const { return m_loaded; }

QString ModelFileLoader::lastError() const { return m_lastError; }

QString ModelFileLoader::getFullTexturePath(const QString &texturePath) const
{
    if (texturePath.isEmpty())
        return QString();

    if (QFileInfo(texturePath).isAbsolute())
        return texturePath;

    return m_modelDirectory + "/" + texturePath;
}

QVector<Triangle> ModelFileLoader::getTriangles() const { return m_triangles; }

QVector<Edge> ModelFileLoader::getEdges() const { return m_edges; }

QVector<QVector<Vertex>> ModelFileLoader::getVertices() const { return m_vertices; }

QVector<QVector<unsigned int>> ModelFileLoader::getVerticesIndices() const { return m_indices; }

QVector<Material> ModelFileLoader::getMaterials() const { return m_materials; }

QVector<Light> ModelFileLoader::getLights() const { return m_lights; }

QVector3D ModelFileLoader::getMinBounds() const { return m_minBounds; }

QVector3D ModelFileLoader::getMaxBounds() const { return m_maxBounds; }

bool ModelFileLoader::hasTexture() const
{
    if(!m_loaded) return false;
    return !(m_materials.size() == 1 && m_materials.front().diffuseTexturePath.isEmpty() && m_materials.front().normalTexturePath.isEmpty() && m_materials.front().specularTexturePath.isEmpty()
             || (m_materials.size() == 1 && m_materials.front().embeddedDiffuseTexture.isEmpty() && m_materials.front().embeddedNormalTexture.isEmpty() && m_materials.front().embeddedSpecularTexture.isEmpty()));
}

void ModelFileLoader::processNode(aiNode* node, const aiScene* scene)
{
    // 处理当前节点的网格
    for (unsigned int i = 0; i < node->mNumMeshes; ++i)
    {
        unsigned int meshIndex = node->mMeshes[i];
        aiMesh* mesh = scene->mMeshes[meshIndex];
        processMesh(mesh, scene);
    }

    // 递归处理子节点
    for (unsigned int i = 0; i < node->mNumChildren; ++i)
    {
        processNode(node->mChildren[i], scene);
    }
}

// 获取纹理像素颜色（根据纹理坐标）
QVector4D sampleTexture(const QVector2D& texCoord, const QImage& diff_img, const QImage& spec_img)
{
    // -------------------------- 1. 前置校验 --------------------------
    // if (diff_img.isNull() || spec_img.isNull()) {
    //     qWarning() << "Texture is null!";
    //     return QVector4D(1.0f, 1.0f, 1.0f, 1.0f);
    // }

    // 确保纹理格式正确
    QImage diffuse = diff_img;
    // QImage specular = spec_img;
    if (diffuse.format() != QImage::Format_RGBA8888)
        diffuse = diffuse.convertToFormat(QImage::Format_RGBA8888);
    // if (specular.format() != QImage::Format_RGBA8888)
    //     specular = specular.convertToFormat(QImage::Format_RGBA8888);

    int texW = diffuse.width();
    int texH = diffuse.height();
    if (texW <= 0 || texH <= 0) {
        return QVector4D(1.0f, 1.0f, 1.0f, 1.0f);
    }

    // -------------------------- 2. 纹理坐标处理 --------------------------
    // 处理超出范围的纹理坐标：使用重复包裹（repeat）模式
    float u = texCoord.x();
    float v = texCoord.y();

    // 包裹处理（保持原样）
    u = u - floor(u);
    v = v - floor(v);

    int x = static_cast<int>(u * texW);
    int y = static_cast<int>(v * texH);
    x = qBound(0, x, texW - 1);
    y = qBound(0, y, texH - 1);
    // qDebug() << "UV: (" << u << "," << v << ") -> Pixel: (" << x << "," << y << ")";

    // -------------------------- 3. 采样纹理 --------------------------
    const uchar* diffData = diffuse.constBits();
    int diffIdx = (y * texW + x) * 4;
    float diffR = diffData[diffIdx + 0] / 255.0f;
    float diffG = diffData[diffIdx + 1] / 255.0f;
    float diffB = diffData[diffIdx + 2] / 255.0f;

    // const uchar* specData = specular.constBits();
    // int specIdx = (y * texW + x) * 4;
    // float specR = specData[specIdx + 0] / 255.0f;
    // float specG = specData[specIdx + 1] / 255.0f;
    // float specB = specData[specIdx + 2] / 255.0f;
    // float specA = specData[specIdx + 3] / 255.0f;

    // -------------------------- 4. 颜色混合 --------------------------
    // float mixedR = qBound(0.0f, diffR/* + specR * specA*/, 1.0f);
    // float mixedG = qBound(0.0f, diffG/* + specG * specA*/, 1.0f);
    // float mixedB = qBound(0.0f, diffB/* + specB * specA*/, 1.0f);
    // float mixedA = 1.0f;

    // float mixedR = qBound(0.0f, diffR + specR * specA, 1.0f);
    // float mixedG = qBound(0.0f, diffG + specG * specA, 1.0f);
    // float mixedB = qBound(0.0f, diffB + specB * specA, 1.0f);
    // float mixedA = 1.0f;

    float mixedR = diffR;
    float mixedG = diffG;
    float mixedB = diffB;
    float mixedA = 1.0f;

    return QVector4D(mixedB, mixedG, mixedR, mixedA);
}

// void ModelFileLoader::processMesh(aiMesh* mesh, const aiScene* scene)
// {
//     int vertexMaterialIndex = mesh->mMaterialIndex;

//     // 容错：材质索引无效时默认用第0个材质
//     if (vertexMaterialIndex < 0 || vertexMaterialIndex >= (int)scene->mNumMaterials)
//         qCritical() << "void ModelFileLoader::processMesh(aiMesh* mesh, const aiScene* scene): Fuck up the index";

//     // 处理顶点数据（存储到m_vertices）
//     QVector<Vertex> verticesPerMaterial(mesh->mNumVertices);
//     std::for_each(std::execution::par, verticesPerMaterial.begin(), verticesPerMaterial.end(),
//         [&](auto& v) {
//             int i = &v - &verticesPerMaterial[0];
//             v.pos = convertAssimpVec3(mesh->mVertices[i]);
//             v.norm = convertAssimpNormal(mesh->mNormals ? mesh->mNormals[i] : aiVector3D(0,0,0));

//             // // 处理颜色（取第一个颜色通道）
//             // v.color = mesh->mColors[0] ?
//             //               QVector4D(mesh->mColors[0][i].r, mesh->mColors[0][i].g, mesh->mColors[0][i].b, mesh->mColors[0][i].a) :
//             //               QVector4D(1.0f, 1.0f, 1.0f, 1.0f);

//             v.texCoord = convertAssimpTexCoord(mesh->mTextureCoords[0] ? mesh->mTextureCoords[0][i] : aiVector3D(0,0,0));

//             // 用CPU采样纹理到外部测试算法用
//             v.color = sampleTexture(v.texCoord, m_textureDiffImage, m_textureSpecImage);

//             v.tangent = convertAssimpVec3(mesh->mTangents ? mesh->mTangents[i] : aiVector3D(0,0,0));

//             v.bitangent = convertAssimpVec3(mesh->mBitangents ? mesh->mBitangents[i] : aiVector3D(0,0,0));

//             v.materialIndex = vertexMaterialIndex;
//         }
//     );
//     m_vertices.append(verticesPerMaterial);

//     // 处理顶点索引
//     unsigned int totalIndices = 0;
//     std::vector<unsigned int> offsets(mesh->mNumFaces);
//     for(unsigned int i = 0; i < mesh->mNumFaces; i++)
//     {
//         offsets[i] = totalIndices;
//         totalIndices += mesh->mFaces[i].mNumIndices;
//     }
//     QVector<unsigned int> indicesPerMaterial(totalIndices);
//     std::vector<unsigned int> faceIndices(mesh->mNumFaces);
//     std::iota(faceIndices.begin(), faceIndices.end(), 0);
//     std::for_each(std::execution::par, faceIndices.begin(), faceIndices.end(),
//         [&](unsigned int faceIdx) {
//             const aiFace& face = mesh->mFaces[faceIdx];
//             unsigned int start = offsets[faceIdx];

//             for(unsigned int j = 0; j < face.mNumIndices; j++)
//                 indicesPerMaterial[start + j] = face.mIndices[j];
//         }
//     );
//     m_indices.append(indicesPerMaterial);

//     // 处理三角形网格（存储到m_triangles）
//     m_triangles = QVector<Triangle>(mesh->mNumFaces); // Mark(mengjinlang): assimp 库必须对所有面三角化才能这样做
//     std::for_each(std::execution::par, m_triangles.begin(), m_triangles.end(),
//         [&](auto& triangle) {
//             int i = &triangle - &m_triangles[0];
//             aiFace& face = mesh->mFaces[i];

//             // 获取顶点索引
//             unsigned int idx1 = face.mIndices[0];
//             unsigned int idx2 = face.mIndices[1];
//             unsigned int idx3 = face.mIndices[2];

//             triangle.v1 = convertAssimpVec3(mesh->mVertices[face.mIndices[0]]);
//             triangle.v2 = convertAssimpVec3(mesh->mVertices[face.mIndices[1]]);
//             triangle.v3 = convertAssimpVec3(mesh->mVertices[face.mIndices[2]]);

//             triangle.v1_color = verticesPerMaterial[idx1].color;
//             triangle.v2_color = verticesPerMaterial[idx2].color;
//             triangle.v3_color = verticesPerMaterial[idx3].color;

//             // 计算面法线
//             QVector3D edge1 = triangle.v2 - triangle.v1;
//             QVector3D edge2 = triangle.v3 - triangle.v1;
//             triangle.normal = QVector3D::crossProduct(edge1, edge2).normalized();
//         }
//     );
//     qDebug() << "Loaded Triangles: " << m_triangles.size();

//     std::vector<Edge> edgesVector(3 * m_triangles.size());
//     std::for_each(std::execution::par, m_triangles.begin(), m_triangles.end(),
//         [&](const Triangle& t){
//             int i = &t - &m_triangles[0];
//             // 每个三角形的三条边
//             Edge e1{Vertex{t.v1, t.normal, t.v1_color}, Vertex{t.v2, t.normal, t.v2_color}, t.normal};
//             Edge e2{Vertex{t.v2, t.normal, t.v2_color}, Vertex{t.v3, t.normal, t.v3_color}, t.normal};
//             Edge e3{Vertex{t.v3, t.normal, t.v3_color}, Vertex{t.v1, t.normal, t.v1_color}, t.normal};

//             edgesVector[3 * i] = e1;
//             edgesVector[3 * i + 1] = e2;
//             edgesVector[3 * i + 2] = e3;
//         }
//     );

//     // 去重
//     std::sort(edgesVector.begin(), edgesVector.end());
//     auto last = std::unique(edgesVector.begin(), edgesVector.end());
//     edgesVector.erase(last, edgesVector.end());
//     m_edges = QVector<Edge>(edgesVector.begin(), edgesVector.end());
//     qDebug() << "Loaded Edges: " << m_edges.size();
// }

void ModelFileLoader::processMesh(aiMesh* mesh, const aiScene* scene)
{
    int vertexMaterialIndex = mesh->mMaterialIndex;

    // 容错：材质索引无效时默认用第0个材质
    if (vertexMaterialIndex < 0 || vertexMaterialIndex >= (int)scene->mNumMaterials) {
        qCritical() << "void ModelFileLoader::processMesh(aiMesh* mesh, const aiScene* scene): Invalid material index";
        vertexMaterialIndex = 0; // 设置默认值而不是直接崩溃
    }

    // 处理顶点数据（顺序执行）
    QVector<Vertex> verticesPerMaterial(mesh->mNumVertices);
    for (int i = 0; i < mesh->mNumVertices; ++i) {
        Vertex& v = verticesPerMaterial[i];
        v.pos = convertAssimpVec3(mesh->mVertices[i]);
        v.norm = convertAssimpNormal(mesh->mNormals ? mesh->mNormals[i] : aiVector3D(0,0,0));
        v.texCoord = convertAssimpTexCoord(mesh->mTextureCoords[0] ? mesh->mTextureCoords[0][i] : aiVector3D(0,0,0));

        // 用CPU采样纹理到外部测试算法用
        v.color = sampleTexture(v.texCoord, m_textureDiffImage, m_textureSpecImage);

        v.tangent = convertAssimpVec3(mesh->mTangents ? mesh->mTangents[i] : aiVector3D(0,0,0));
        v.bitangent = convertAssimpVec3(mesh->mBitangents ? mesh->mBitangents[i] : aiVector3D(0,0,0));
        v.materialIndex = vertexMaterialIndex;
    }
    m_vertices.append(verticesPerMaterial);

    // 处理顶点索引
    QVector<unsigned int> indicesPerMaterial;
    for(unsigned int i = 0; i < mesh->mNumFaces; i++) {
        const aiFace& face = mesh->mFaces[i];
        for(unsigned int j = 0; j < face.mNumIndices; j++) {
            indicesPerMaterial.append(face.mIndices[j]);
        }
    }
    m_indices.append(indicesPerMaterial);

    // 处理三角形网格
    m_triangles = QVector<Triangle>(mesh->mNumFaces);
    for(int i = 0; i < mesh->mNumFaces; i++) {
        const aiFace& face = mesh->mFaces[i];
        Triangle& triangle = m_triangles[i];

        // 获取顶点索引
        unsigned int idx1 = face.mIndices[0];
        unsigned int idx2 = face.mIndices[1];
        unsigned int idx3 = face.mIndices[2];

        triangle.v1 = convertAssimpVec3(mesh->mVertices[idx1]);
        triangle.v2 = convertAssimpVec3(mesh->mVertices[idx2]);
        triangle.v3 = convertAssimpVec3(mesh->mVertices[idx3]);

        triangle.v1_color = verticesPerMaterial[idx1].color;
        triangle.v2_color = verticesPerMaterial[idx2].color;
        triangle.v3_color = verticesPerMaterial[idx3].color;

        // 计算面法线
        QVector3D edge1 = triangle.v2 - triangle.v1;
        QVector3D edge2 = triangle.v3 - triangle.v1;
        triangle.normal = QVector3D::crossProduct(edge1, edge2).normalized();
    }
    qDebug() << "Loaded Triangles: " << m_triangles.size();

    // 处理边（顺序执行）
    std::vector<Edge> edgesVector;
    for(const Triangle& t : m_triangles) {
        Edge e1{Vertex{t.v1, t.normal, t.v1_color}, Vertex{t.v2, t.normal, t.v2_color}, t.normal};
        Edge e2{Vertex{t.v2, t.normal, t.v2_color}, Vertex{t.v3, t.normal, t.v3_color}, t.normal};
        Edge e3{Vertex{t.v3, t.normal, t.v3_color}, Vertex{t.v1, t.normal, t.v1_color}, t.normal};

        edgesVector.push_back(e1);
        edgesVector.push_back(e2);
        edgesVector.push_back(e3);
    }

    // 去重
    std::sort(edgesVector.begin(), edgesVector.end());
    auto last = std::unique(edgesVector.begin(), edgesVector.end());
    edgesVector.erase(last, edgesVector.end());
    m_edges = QVector<Edge>(edgesVector.begin(), edgesVector.end());
    qDebug() << "Loaded Edges: " << m_edges.size();
}

void ModelFileLoader::processTextures(aiMaterial* material, aiTextureType type,
                                      QString& texturePath, QByteArray& embeddedTextureData)
{
    if (material->GetTextureCount(type) > 0)
    {
        aiString path;
        aiTextureMapping mapping;
        unsigned int uvindex;
        float blend;
        aiTextureOp op;
        aiTextureMapMode mapmode;

        if (material->GetTexture(type, 0, &path, &mapping, &uvindex, &blend, &op, &mapmode) == AI_SUCCESS)
        {
            // 检查是否是嵌入式纹理（路径以'*'开头）
            if (path.data[0] == '*')
            {
                // 嵌入式纹理
                int texIndex = atoi(path.C_Str() + 1);
                if (m_scene && texIndex >= 0 && texIndex < (int)m_scene->mNumTextures)
                {
                    aiTexture* embeddedTex = m_scene->mTextures[texIndex];

                    if (embeddedTex->mHeight == 0)
                    {
                        // 压缩格式纹理（如JPEG, PNG）
                        embeddedTextureData = QByteArray(reinterpret_cast<char*>(embeddedTex->pcData),
                                                         embeddedTex->mWidth);
                    }
                    else
                    {
                        // 未压缩的ARGB纹理
                        // 这里可以处理未压缩纹理，但通常GLB使用压缩格式
                    }
                    texturePath = QString("*embedded_%1").arg(texIndex);
                }
            }
            else
            {
                // 外部文件纹理
                texturePath = QString::fromUtf8(path.C_Str());
            }
        }
    }
}

void ModelFileLoader::processMaterial(aiMaterial *material, Material &outMaterial)
{
    // 材质名称
    aiString name;
    if (material->Get(AI_MATKEY_NAME, name) == AI_SUCCESS)
        outMaterial.name = QString(name.C_Str());

    // 基本颜色属性
    aiColor3D ambient, diffuse, specular;
    float shininess;

    // 安全地获取材质属性
    if (material->Get(AI_MATKEY_COLOR_AMBIENT, ambient) != AI_SUCCESS)
        ambient = aiColor3D(0.2f, 0.2f, 0.2f);

    if (material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse) != AI_SUCCESS)
        diffuse = aiColor3D(0.8f, 0.8f, 0.8f);

    if (material->Get(AI_MATKEY_COLOR_SPECULAR, specular) != AI_SUCCESS)
        specular = aiColor3D(0.5f, 0.5f, 0.5f);

    if (material->Get(AI_MATKEY_SHININESS, shininess) != AI_SUCCESS || shininess <= 0.0f || shininess > 1024.0f)
        shininess = 32.0f;

    outMaterial.ambient = QVector3D(ambient.r, ambient.g, ambient.b);
    outMaterial.diffuse = QVector3D(diffuse.r, diffuse.g, diffuse.b);
    outMaterial.specular = QVector3D(specular.r, specular.g, specular.b);
    outMaterial.shininess = shininess;

    // 处理纹理 - 支持嵌入式纹理
    processTextures(material, aiTextureType_DIFFUSE, outMaterial.diffuseTexturePath, outMaterial.embeddedDiffuseTexture);
    processTextures(material, aiTextureType_SPECULAR, outMaterial.specularTexturePath, outMaterial.embeddedSpecularTexture);
    processTextures(material, aiTextureType_NORMALS, outMaterial.normalTexturePath, outMaterial.embeddedNormalTexture);
    processTextures(material, aiTextureType_HEIGHT, outMaterial.normalTexturePath, outMaterial.embeddedNormalTexture); // 高度图也作为法线图
}

void ModelFileLoader::fillImageWithTexture(const QVector<Material> &materials)
{
    bool isFilled = false;

    for(const auto& mat : materials)
    {
        qDebug() << "处理材质:" << mat.name;
        qDebug() << "外部纹理路径:" << mat.diffuseTexturePath;
        qDebug() << "嵌入式纹理大小:" << mat.embeddedDiffuseTexture.size();

        // 优先检查嵌入式纹理数据
        if(!mat.embeddedDiffuseTexture.isEmpty())
        {
            if (m_textureDiffImage.loadFromData(mat.embeddedDiffuseTexture))
            {
                m_textureDiffImage = m_textureDiffImage.convertToFormat(QImage::Format_RGBA8888);
                qDebug() << "成功加载嵌入式纹理";
                // if (m_textureDiffImage.save("nzmt_diff.jpg"))
                // {
                //     qDebug() << "成功加载并保存嵌入式纹理";
                //     isFilled = true;
                // }
                // else
                // {
                //     qWarning() << "保存纹理文件失败";
                // }
            }
            else
            {
                qWarning() << "无法从嵌入式数据加载纹理";
                QImage image;
                const char* formats[] = {"JPG", "JPEG", "PNG", "BMP", nullptr};
                for (int i = 0; formats[i] != nullptr; ++i)
                {
                    if (image.loadFromData(mat.embeddedDiffuseTexture, formats[i]))
                    {
                        m_textureDiffImage = image.convertToFormat(QImage::Format_RGBA8888);
                        // m_textureDiffImage.save("nzmt_diff." + QString(formats[i]).toLower());
                        isFilled = true;
                        qDebug() << "使用格式" << formats[i] << "成功加载纹理";
                        break;
                    }
                }

                if (!isFilled)
                {
                    qWarning() << "所有格式尝试都失败";
                }
            }
        }
        // 检查是否是嵌入式纹理标识符（如 "*embedded_0"）
        else if(!mat.diffuseTexturePath.isEmpty() && mat.diffuseTexturePath.startsWith("*embedded"))
        {
            qDebug() << "检测到嵌入式纹理标识符:" << mat.diffuseTexturePath;
            qWarning() << "有嵌入式纹理标识符但没有对应的嵌入式数据，可能解析有问题";
        }
        // 检查真实的外部文件路径
        else if(!mat.diffuseTexturePath.isEmpty() && QFile::exists(getFullTexturePath(mat.diffuseTexturePath)))
        {
            if (!m_textureDiffImage.load(getFullTexturePath(mat.diffuseTexturePath)))
            {
                qWarning() << "无法加载纹理：" << getFullTexturePath(mat.diffuseTexturePath);
            }
            else
            {
                m_textureDiffImage = m_textureDiffImage.convertToFormat(QImage::Format_RGBA8888);
                isFilled = true;
                qDebug() << "成功加载外部纹理";
            }
        }
        else if(!mat.diffuseTexturePath.isEmpty())
        {
            qWarning() << "纹理文件不存在：" << getFullTexturePath(mat.diffuseTexturePath);
        }

        if(isFilled)
        {
            break;
        }
    }

    if (!isFilled)
    {
        qWarning() << "未能加载任何纹理";
    }
}

void ModelFileLoader::processLights(const aiScene *scene)
{
    for (unsigned int i = 0; i < scene->mNumLights; ++i) {
        aiLight* aiLight = scene->mLights[i];
        Light light;

        // 灯光类型
        switch (aiLight->mType) {
        case aiLightSource_DIRECTIONAL: light.type = Light::Directional; break;
        case aiLightSource_POINT: light.type = Light::Point; break;
        case aiLightSource_SPOT: light.type = Light::Spot; break;
        default: continue; // 忽略其他类型
        }

        // 颜色
        light.color = QVector3D(
            aiLight->mColorDiffuse.r,
            aiLight->mColorDiffuse.g,
            aiLight->mColorDiffuse.b
            );

        // 位置和方向
        light.position = convertAssimpVec3(aiLight->mPosition);
        light.direction = convertAssimpVec3(aiLight->mDirection);

        // 衰减参数（点光/聚光灯）
        light.constant = aiLight->mAttenuationConstant;
        light.linear = aiLight->mAttenuationLinear;
        light.quadratic = aiLight->mAttenuationQuadratic;

        // 聚光灯参数
        light.cutOff = aiLight->mAngleInnerCone * 180.0f / M_PI; // 弧度转度
        light.outerCutOff = aiLight->mAngleOuterCone * 180.0f / M_PI;

        m_lights.push_back(light);
    }
}

// void ModelFileLoader::calculateBounds()
// {
//     for (const auto& v : m_vertices)
//     {
//         m_minBounds.setX(qMin(m_minBounds.x(), v.pos.x()));
//         m_minBounds.setY(qMin(m_minBounds.y(), v.pos.y()));
//         m_minBounds.setZ(qMin(m_minBounds.z(), v.pos.z()));

//         m_maxBounds.setX(qMax(m_maxBounds.x(), v.pos.x()));
//         m_maxBounds.setY(qMax(m_maxBounds.y(), v.pos.y()));
//         m_maxBounds.setZ(qMax(m_maxBounds.z(), v.pos.z()));
//     }
// }

QVector3D ModelFileLoader::convertAssimpVec3(const aiVector3D &vec) const
{
    // Assimp的Y轴可能与OpenGL相反，根据需求调整
    return QVector3D(vec.x, vec.y, vec.z);
}

QVector3D ModelFileLoader::convertAssimpNormal(const aiVector3D &normal) const
{
    // 法线方向需与坐标转换一致
    return QVector3D(normal.x, normal.y, normal.z).normalized();
}

QVector2D ModelFileLoader::convertAssimpTexCoord(const aiVector3D &texCoord) const
{
    // Assimp的纹理坐标可能是3D的，但我们通常只需要前两个分量
    return QVector2D(texCoord.x, texCoord.y);
}
